module window_3x3#(
	parameter PIX_PER_LINE = 320,
	parameter PIX_DOUBLE_LINE = 640
)(
						input 			  clock,
						input 			  frame_reset,
						input[15:0] 	  datain,
						input 			  datain_en,
						output reg[15:0] data00,
						output reg[15:0] data01,
						output reg[15:0] data02,
						
						output reg[15:0] data10,
						output reg[15:0] data11,
						output reg[15:0] data12,
						
						output reg[15:0] data20,
						output reg[15:0] data21,
						output reg[15:0] data22,
						
						output reg		  data_valid
						);
						
	
	reg 		  	line_buf_rden;
	reg 		  	line_buf_rden_d1;
	wire[15:0] 		line_buf_dout;
	wire[15:0] 		line_dout00;
	wire[15:0] 		line_dout01;
	wire[9:0]  		line_buf_data_count;
	wire[9:0]  		line_data_count00;
	wire[9:0]  		line_data_count01;
	wire		  	line_rden0;
	wire		  	line_rden1;
	reg[9:0]   		line_buf_rd_cnt;
	reg[10:0]  		line_rden_cnt;
	reg		  		line_data_valid;
	reg		  		line_data_valid_d1,line_data_valid_d2;
	
	reg [9:0] hcnt;
	reg [9:0] vcnt;
	// assign line_rden0 = (line_data_count00 >= PIX_PER_LINE - 1) ? line_buf_rden : 1'b0;
	// assign line_rden1 = (line_data_count01 >= PIX_PER_LINE - 1) ? line_buf_rden : 1'b0;
	assign line_rden0 = (line_data_count00 >= PIX_PER_LINE ) ? line_buf_rden : 1'b0;
	assign line_rden1 = (line_data_count01 >= PIX_PER_LINE ) ? line_buf_rden : 1'b0;
	
	always @(posedge clock)
	begin
		if(frame_reset)
			line_buf_rden <= 1'b0;
		else if(line_buf_data_count >= PIX_PER_LINE)
			line_buf_rden <= 1'b1;
		else if(line_buf_rd_cnt == PIX_PER_LINE - 1)
			line_buf_rden <= 1'b0;
	end
	
	always @(posedge clock)
	begin
		if(frame_reset)
			line_buf_rd_cnt <= 10'd0;
		else if(line_buf_rden)
			line_buf_rd_cnt <= line_buf_rd_cnt + 1'b1;
		else
			line_buf_rd_cnt <= 10'd0;
	end
	
	always @(posedge clock)
	begin
		line_buf_rden_d1 <= line_buf_rden;
	end
	
	always @(posedge clock)
	begin
		if(frame_reset)
			line_rden_cnt <= 11'd0;
		else if(line_buf_rden) begin
			if(line_rden_cnt < PIX_DOUBLE_LINE)
				line_rden_cnt <= line_rden_cnt + 1'b1;
			else
				line_rden_cnt <= line_rden_cnt;
		end
		else
			line_rden_cnt <= line_rden_cnt;
	end
	
	always @(posedge clock)
	begin
		if(frame_reset)
			line_data_valid <= 1'b0;
		else if(line_rden_cnt == PIX_DOUBLE_LINE)
			line_data_valid <= line_buf_rden;
		else
			line_data_valid <= 1'b0;
	end
	
	always @(posedge clock)
	begin
		if(frame_reset) begin
			data00 <= 16'h0;
			data01 <= 16'h0;
			data02 <= 16'h0;
			
			data10 <= 16'h0;
			data11 <= 16'h0;
			data12 <= 16'h0;
			
			data20 <= 16'h0;
			data21 <= 16'h0;
			data22 <= 16'h0;
			
			line_data_valid_d1 <= 1'b0;
			line_data_valid_d2 <= 1'b0;
		end
		else begin
			// data22 <= (vcnt<510) ? line_buf_dout : line_dout01;
			data22 <= line_buf_dout;
			data21 <= data22;
			data20 <= data21;
			
			data12 <= line_dout00;
			// data12 <= (vcnt<511) ? line_dout00 : line_dout01;
			data11 <= data12;
			data10 <= data11;
			
			data02 <= line_dout01;
			// data02 <= (vcnt<512) ? line_dout01 : 0;
			data01 <= data02;
			data00 <= data01;
			
			line_data_valid_d1 <= line_data_valid;
			line_data_valid_d2 <= line_data_valid_d1;
			// data_valid			 <= line_data_valid_d2;
			data_valid			 <= line_data_valid_d1;
			// data_valid			 <= line_data_valid;
		end
	end	
	fifo #(.DATA_W(16),.DEPT_W(2048) )inst_board_sync1(
                   .aclr    ( frame_reset			),
                   .wrclk   ( clock					),
                   .wrreq   ( datain_en				),
                   .data    ( datain				),
                   .rdclk   ( clock					),//24mhz from test-board pll
                   .rdreq   ( line_buf_rden			),
                   .q       ( line_buf_dout			),
                   .wrusedw ( line_buf_data_count	)
);  
	// enfifo1024x16 line_buf(
	// 	.aclr		(frame_reset),
	// 	.clock		(clock),
	// 	.data		(datain),
	// 	.rdreq		(line_buf_rden),
	// 	.wrreq		(datain_en),
	// 	.q			(line_buf_dout),
	// 	.usedw		(line_buf_data_count)
	// 	);
		
	fifo #(.DATA_W(16),.DEPT_W(2048) )inst_board_sync2(
                   .aclr    ( frame_reset			),
                   .wrclk   ( clock					),
                //    .wrreq   ( line_buf_rden_d1				),
                   .wrreq   ( line_buf_rden				),
                   .data    ( line_buf_dout				),
                   .rdclk   ( clock					),//24mhz from test-board pll
                   .rdreq   ( line_rden0			),
                   .q       ( line_dout00			),
                   .wrusedw ( line_data_count00	)
);  
	// enfifo1024x16 line_00(
	// 	.aclr		(frame_reset),
	// 	.clock		(clock),
	// 	.data		(line_buf_dout),
	// 	.rdreq		(line_rden0),
	// 	.wrreq		(line_buf_rden_d1),
	// 	.q			(line_dout00),
	// 	.usedw		(line_data_count00)
	// 	);
	
	fifo #(.DATA_W(16),.DEPT_W(2048) )inst_board_sync3(
                   .aclr    ( frame_reset		),
                   .wrclk   ( clock				),
                //    .wrreq   ( line_buf_rden_d1	),
                   .wrreq   ( line_rden0	),
                   .data    ( line_dout00		),
                   .rdclk   ( clock				),//24mhz from test-board pll
                   .rdreq   ( line_rden1		),
                   .q       ( line_dout01		),
                   .wrusedw ( line_data_count01	)
);  
	// enfifo1024x16 line_01(
	// 	.aclr		(frame_reset),
	// 	.clock		(clock),
	// 	.data		(line_dout00),
	// 	.rdreq		(line_rden1),
	// 	.wrreq		(line_buf_rden_d1),
	// 	.q			(line_dout01),
	// 	.usedw		(line_data_count01)
	// 	);


reg 	  data_valid_r1;
always @ ( posedge clock ) begin
	if( frame_reset ) begin
		data_valid_r1 <= 1'd0;
	end
	else begin
		data_valid_r1 <= data_valid;
	end
end
always @ ( posedge clock ) begin
	if( frame_reset ) begin
		hcnt        <=        'd0;
	end
	else if( data_valid)begin
		hcnt        <=        hcnt + 'd1;
	end
	else begin
		hcnt        <=        'd0;
	end
end
always @ ( posedge clock ) begin
	if( frame_reset ) begin
		vcnt        <=        'd0;
	end
	else if( data_valid_r1 && (~data_valid) )begin
		vcnt        <=        vcnt + 'd1;
	end
	else begin
		vcnt        <=        vcnt;
	end
end

endmodule 